package com.kancy.jemeter.functions;

import com.kancy.jemeter.util.StringUtil;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.FileWrapper;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.threads.JMeterVariables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author kancy
 * @date 2019/6/29 17:02
 */
public abstract class JemeterAbstractFunction extends AbstractFunction {
	protected static final Logger log = LoggerFactory.getLogger(FileWrapper.class);

	private static final Map<String, List<String>> argumentDescMaplist = new HashMap();

	private static final String KEY_PREFIX = "__";

	private List<CompoundVariable> parametersList;
	private int minParameterCount = 0;
	private int maxParameterCount = 0;

	public JemeterAbstractFunction() {
		log.debug("{} function Initialization !", getReferenceKey());
	}

	public JemeterAbstractFunction(int parameterCount) {
		this();
		this.minParameterCount = parameterCount;
		this.maxParameterCount = parameterCount;
	}
	public JemeterAbstractFunction(int minParameterCount, int maxParameterCount) {
		this();
		assert maxParameterCount >= minParameterCount;
		assert minParameterCount >= 0;
		this.minParameterCount = minParameterCount;
		this.maxParameterCount = maxParameterCount;
	}

	@Override
	public final void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
		if ((minParameterCount == 0 && maxParameterCount == 0 ) || parameters.isEmpty()){
			return;
		}
		this.checkParameterCount(parameters, minParameterCount, maxParameterCount);
		Object[] values = parameters.toArray();

		parametersList = new ArrayList(values.length);
		String referenceKey = getReferenceKey();
		for (int i = 0; i < values.length; i++) {
			CompoundVariable variable = (CompoundVariable) values[i];
			parametersList.add(variable);
			log.debug("{} function parametersList{}: {}",referenceKey, i, variable.execute().trim());
		}
	}

	protected final String getParameter(int index,String def) {
		if(!hasParameter() || index >= parametersList.size()){
			return def;
		}
		String trim = parametersList.get(index).execute().trim();

		if(StringUtil.isEmpty(trim)){
			return def;
		}
		return trim;
	}

	protected final String getParameter(int index) {
		return getParameter(index,"");
	}

	protected final boolean hasParameter(){
		return parametersList!=null && !parametersList.isEmpty();
	}

	protected final boolean hasParameter(int index){
		return hasParameter() && index >= 0 && index < parametersList.size()
				&& !StringUtil.isEmpty(getParameter(index));
	}

	protected final String setJMeterVariable(int parameterIndex, String result) {
		if(hasParameter(parameterIndex)){
			JMeterVariables vars = this.getVariables();
			String parameter = getParameter(parameterIndex);
			vars.put(parameter, result);
			log.debug("{} function getParameter{} is {} ", getReferenceKey(), parameterIndex, parameter);
		}
		return result;
	}

	@Override
	public String getReferenceKey() {
		String className = KEY_PREFIX + getClass().getSimpleName();
		if(className.endsWith("Function")){
			return className.replace("Function", "").toLowerCase();
		}
		return className.toLowerCase();
	}
}
